package com.business.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.business.common.dto.R;
import com.business.common.enums.BusinessExceptionEnum;
import com.business.common.utils.FormatValidUtil;
import com.business.common.utils.JSONUtil;
import com.business.common.utils.RandomHelper;
import com.business.redis.ExpiresTimeEnum;
import com.business.redis.constant.RedisKeyConstant;
import com.business.redis.utils.RedisKeysUtil;
import com.business.redis.utils.RedisUtil;
import com.business.user.entity.UserDto;
import com.business.user.rabbitMq.RabbitMqSender;
import com.business.user.utils.UserUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 短信验证码
 *
 * @author chenjiehong
 * @date 2018-11-09 10:02:20
 */

@RestController
public class ValidateCodeController {

    private static final Logger logger = LoggerFactory
            .getLogger(ValidateCodeController.class);

    @Autowired
    private RabbitMqSender rabbitMqSender;

    /**
     * 获取验证码接口
     *
     * @return
     * @throws ClientException
     */
    @PostMapping("/getVerificationCode")
    @ResponseBody
    public R getVerificationCode(@RequestBody JSONObject params) {

        String phone = params.getString("phone");
        logger.info("getVerificationCode phone = " + phone);
        if (StringUtils.isBlank(phone)) {
            return R.error(BusinessExceptionEnum.PHONE_NULL);
        }
        if (!FormatValidUtil.matchPhone(phone)) {
            return R.error(BusinessExceptionEnum.PHONE_PATTERN_ERROR);
        }
        //判断是否频繁获取
        String key = String.format(RedisKeyConstant.USER_GET_VERIFICATION_CODE_FLAG, phone);
        if (!RedisUtil.setIfAbsent(key, 1, ExpiresTimeEnum.GET_VALIDATE_CODE_FLAG.getExpiresTime())) {
            return R.error(BusinessExceptionEnum.VERIFICATION_IS_NOT_OVERTIME);
        }
        // 发送到消息队列，发送短信
        rabbitMqSender.sendVerificationCode(phone);
        return R.success();
    }

    /**
     * 获取验证码接口
     *
     * @param params
     * @return
     */
    @PostMapping("/getVerificationCodeTest")
    @ResponseBody
    public R getVerificationCodeTest(@RequestBody JSONObject params) {
        String phone = params.getString("phone");

        //R R = new R(0, "获取验证码成功");
        if (StringUtils.isBlank(phone)) {
            return R.error(BusinessExceptionEnum.PHONE_NULL);
        }
        if (!FormatValidUtil.matchPhone(phone)) {
            return R.error(BusinessExceptionEnum.PHONE_PATTERN_ERROR);
        }
        String existCode = (String) RedisUtil.getValue(phone);
        if (StringUtils.isNotBlank(existCode)) {
            String existCodeJsonString = JSONUtil.stringToJsonByFastjson(
                    "verificationCode", existCode);
            return R.success(existCodeJsonString);
        }
        String code = RandomHelper.numberic(4) + "";
        logger.info("validate Code = " + code);

        // 将验证码缓存到redis
        String key = String.format(RedisKeyConstant.USER_GET_VERIFICATION_CODE, phone);
        RedisUtil.setValue(key, code, ExpiresTimeEnum.VALIDATE_CODE.getExpiresTime());
        String codeJsonString = JSONUtil.stringToJsonByFastjson(
                "verificationCode", code);
        return R.success(codeJsonString);
    }

    /**
     * 验证验证码接口
     *
     * @param phone
     * @param code
     * @return
     */
    @PostMapping("/checkVerificationCode")
    @ResponseBody
    public R checkVerificationCode(@RequestBody String phone,
                                   @RequestBody String code) {
        logger.info("checkVerificationCode: phone = " + phone
                + " validate Code = " + code);
        return R.success(UserUtil.validateCode(phone, code));
    }

}
